#pragma once

#include <vector>
#include <map>
#include "Config.hpp"
#include "zen_random.h"
#include "zen_log.h"


extern Zen::Random g_random;

static const int GMapHeight = 20;
static const int GMapWidth = 10;
static const int GMapEdge = 4;
static const int GBlockColorCount = 5;
static const int GDirectCount = 4;
static const int GPotsMaxCount = 4;

using namespace Zen;

struct Map {
	int value[GMapHeight+GMapEdge][GMapWidth];

	int get_value_at(int x, int y) const {

		return value[y][x];
	}
	void reset(int v = 0) {
		::memset(&value, v, sizeof(value));
	}
	void reset_line(int y, int v) {
		if(y < 0 || y >= GMapHeight + GMapEdge)
		{
			LogE("out of map:y= %d", y);
			return;
		}
		::memset(value[y], v, sizeof(value[y]));
	}
	void copy_line(int dest, int src) {
		::memcpy(value[dest], value[src], sizeof(value[src]));
	}
	void set(int x, int y, int v)
	{
		if(x < 0 || x >= GMapWidth || y < 0 || y >= GMapHeight + GMapEdge)
		{
			LogE("out of map:%d %d", x, y);
			return;
		}

		value[y][x] = v;
	}
};

struct Pos {
	int x, y;
};

enum TetrisType {
	TetrisTypeO = 0, // rect
	TetrisTypeL = 1, // L
	TetrisTypeJ = 2, // J
	TetrisTypeS = 3, //
	TetrisTypeZ = 4, //
	TetrisTypeI = 5, // |
	TetrisTypeT = 6,
	TetrisTypeNormalCount = 7,
	TetrisTypeI1 = 7,
	TetrisTypeI2 = 8,
	TetrisTypeI3 = 9,
	TetrisTypeCount,
	TetrisTypeNone = -1,
};

struct TetrisInfo {
	enum TetrisType type = TetrisTypeNone;
	int direct = 0;
	int color = 0;
};

struct Result {
	std::vector<int> cleared_lines;
};

class TetrisConfig
{
public:
	TetrisConfig();

	static int GetDirectCount(enum TetrisType type);

	static std::vector<Pos> GetSubPoses(enum TetrisType type, int direct, Pos pos);

	TetrisInfo getNext();

protected:
	bool m_use_special = 1;
	Random random;
};

enum class GestureType {
	Left, Right, Down, QuickDown, Tap, Begin, End
};
